// // 使用像素化功能组件
// // src/components/Pixelator.tsx
// import React, { useRef, useEffect, useState, useCallback } from 'react';
// import { Box, Button, Spinner } from '@chakra-ui/react';
// import { pixelateImage, type PixelationParams, type Palette } from '../utils/pixelator';
// import { debounce } from '../utils/debounce';
// // 日志模块
// import { createLogger } from '../utils/logger';
// // 在现有导入基础上添加
// import { useErrorHandler } from '../hooks/useErrorHandler';
// import { ImageProcessError } from '../utils/errorTypes';

// // ✅ 创建属于本模块的日志实例
// const log = createLogger('pixelator');

// interface PixelatorProps {
//   imageUrl: string;
//   params: PixelationParams;
//   palette?: Palette;
//   onProcessingComplete: (processedImageUrl: string) => void;
// }

// export const Pixelator: React.FC<PixelatorProps> = ({
//   imageUrl,
//   params,
//   palette,
//   onProcessingComplete
// }) => {

//     // 现有状态声明...
//   const { handleError, withErrorHandling } = useErrorHandler();

//     // 修改 processImage 函数
//   const processImage = withErrorHandling(
//     async () => {
//       if (!imageUrl) return;

//       setIsProcessing(true);
//       try {
//         const result = await pixelateImage(imageUrl, params, palette);
//         setProcessedImage(result);
//         setLastProcessedParams({ ...params });
//         setLastProcessedPalette(palette ? { ...palette } : undefined);
//         onProcessingComplete(result);
//       } catch (error) {
//         // 将错误转换为应用错误
//         if (error instanceof Error) {
//           throw new ImageProcessError(error.message);
//         } else {
//           throw new ImageProcessError('Unknown processing error');
//         }
//       } finally {
//         setIsProcessing(false);
//       }
//     },
//     'image-processing'
//   );

//   const canvasRef = useRef<HTMLCanvasElement>(null);
//   const [isProcessing, setIsProcessing] = useState(false);
//   const [processedImage, setProcessedImage] = useState<string | null>(null);
//   const [lastProcessedParams, setLastProcessedParams] = useState<PixelationParams>(params);
//   const [lastProcessedPalette, setLastProcessedPalette] = useState<Palette | undefined>(palette);

//   // 创建防抖处理函数
//   const debouncedProcessImage = useCallback(
//     debounce(() => {
//       if (imageUrl) {
//         processImage();
//       }
//       else{
//       }
//     }, 300),
//     [params, palette, imageUrl]
//   );

//   // 创建不防抖处理函数
//   const DirectlyProcessImage = useCallback(() => {
//     if (imageUrl) {
//       processImage();
//     }
//   },
//    [params, palette, imageUrl]
//   ); // 同样需要确保依赖项完整

//   useEffect(() => {
//     // 只有当参数或调色板实际发生变化时才触发处理
//     const paramsChanged = JSON.stringify(params) !== JSON.stringify(lastProcessedParams);
//     const paletteChanged = JSON.stringify(palette) !== JSON.stringify(lastProcessedPalette);
//     const imageChanged = imageUrl !== ''; // 新图加载（或从无到有）

//     const shouldProcess = (paramsChanged||paletteChanged||imageChanged)&&imageUrl;

//     if (!imageUrl){
//       log.debug('Detected that the image address does not exist');
//     }
//     else{
//       log.debug('Detected the existence of image address');
//     }
//     if (!imageChanged){
//       log.debug('Detected no change in image address');
//     }
//     else{
//       log.debug('Detected a change in image address');
//       // log.debug('imageUrl', imageUrl);
//     }

//     if (!paramsChanged){
//       log.debug('Detected no changes in parameters');
//     }else{
//       log.debug('Detected parameter changes');
//       log.debug('params', params);
//       log.debug('lastProcessedParams', lastProcessedParams);
//     }

//     if (!paletteChanged){
//       log.debug('Detected no change in the color palette');
//     }else{
//       log.debug('Detected a change in the color palette');
//       log.debug('palette', palette);
//       log.debug('lastProcessedPalette', lastProcessedPalette);
//     }


//     if (params.useDithering && shouldProcess) // 首次处理也算
//     {
//       log.info(' Jitter mode: delayed processing');
//       debouncedProcessImage();
//     }
//     else if (!params.useDithering && shouldProcess
//     ) {
//       log.info(' Non jitter mode: Immediate processing');
//       DirectlyProcessImage();
//     }
//     else{
//       log.info(' Parameter not changed: Not processed');
//     }


//   }, [params, palette, imageUrl]);

//   // // 临时修改：直接响应参数变化
//   // useEffect(() => {
//   //   if (imageUrl) {
//   //     processImage();
//   //   }
//   // }, [params, palette, imageUrl]); // 直接依赖所有可能变化的参数

//   // const processImage = async () => {
//   //   if (!imageUrl) return;

//   //   setIsProcessing(true);
//   //   try {
//   //     const result = await pixelateImage(imageUrl, params, palette);
//   //     setProcessedImage(result);
//   //     setLastProcessedParams({ ...params });
//   //     setLastProcessedPalette(palette ? { ...palette } : undefined);
//   //     onProcessingComplete(result);
//   //   } catch (error) {
//   //     console.error('图像处理失败:', error);
//   //   } finally {
//   //     setIsProcessing(false);
//   //   }
//   // }

//   const downloadImage = () => {
//     if (!processedImage) return;

//     const link = document.createElement('a');
//     link.href = processedImage;
//     link.download = 'pixel-art.png';
//     link.click();
//   };

//   if (!imageUrl) {
//     return (
//       <Box border="2px dashed" borderColor="gray.300" p={8} textAlign="center">
//         请先上传图片
//       </Box>
//     );
//   }

//   return (
//     <Box>
//       <Box position="relative" mb={4}>
//         {isProcessing && (
//           <Box
//             position="absolute"
//             top="50%"
//             left="50%"
//             transform="translate(-50%, -50%)"
//             zIndex={10}
//           >
//             <Spinner size="xl" />
//           </Box>
//         )}
//         {processedImage && (
//           <img
//             src={processedImage}
//             alt="Pixelated"
//             style={{
//               width: '100%',
//               maxWidth: '600px',
//               opacity: isProcessing ? 0.5 : 1,
//               transition: 'opacity 0.3s'
//             }}
//           />
//         )}
//       </Box>

//       {processedImage && !isProcessing && (
//         <Button colorScheme="blue" onClick={downloadImage}>
//           下载像素图
//         </Button>
//       )}
//     </Box>
//   );
// };

// 使用像素化功能组件
// src/components/Pixelator.tsx
import React, { useRef, useEffect, useState, useCallback } from 'react';
import { Box, Button, Spinner, useToast, AlertDialog, AlertDialogBody, AlertDialogContent, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay } from '@chakra-ui/react';
import { pixelateImage, type PixelationParams, type Palette } from '../utils/pixelator';
import { debounce } from '../utils/debounce';
// 日志模块
import { createLogger } from '../utils/logger';
import { useErrorHandler } from '../hooks/useErrorHandler';
import { ImageProcessError } from '../utils/errorTypes';

// ✅ 创建属于本模块的日志实例
const log = createLogger('pixelator');

interface PixelatorProps {
  imageUrl: string;
  params: PixelationParams;
  palette?: Palette;
  onProcessingComplete: (processedImageUrl: string) => void;
}

export const Pixelator: React.FC<PixelatorProps> = ({
  imageUrl,
  params,
  palette,
  onProcessingComplete
}) => {
  const { /*handleError, */withErrorHandling } = useErrorHandler();
  // const canvasRef = useRef<HTMLCanvasElement>(null);
  const cancelRef = useRef<HTMLButtonElement>(null);
  const [isProcessing, setIsProcessing] = useState(false);
  const [isDownloading, setIsDownloading] = useState(false);
  const [processedImage, setProcessedImage] = useState<string | null>(null);
  const [lastProcessedParams, setLastProcessedParams] = useState<PixelationParams>(params);
  const [lastProcessedPalette, setLastProcessedPalette] = useState<Palette | undefined>(palette);
  const [showMobileGuide, setShowMobileGuide] = useState(false);
  const toast = useToast();

  // 设备检测函数
  const detectDevice = () => {
    const userAgent = navigator.userAgent;
    const isIOS = /iPad|iPhone|iPod/.test(userAgent) && !(window as any).MSStream;
    const isAndroid = /Android/.test(userAgent);
    const isMobile = isIOS || isAndroid;

    return { isIOS, isAndroid, isMobile };
  };

  // 修改 processImage 函数
  const processImage = withErrorHandling(
    async () => {
      if (!imageUrl) return;

      setIsProcessing(true);
      try {
        const result = await pixelateImage(imageUrl, params, palette);
        setProcessedImage(result);
        setLastProcessedParams({ ...params });
        setLastProcessedPalette(palette ? { ...palette } : undefined);
        onProcessingComplete(result);
      } catch (error) {
        if (error instanceof Error) {
          throw new ImageProcessError(error.message);
        } else {
          throw new ImageProcessError('Unknown processing error');
        }
      } finally {
        setIsProcessing(false);
      }
    },
    'image-processing'
  );

  // 创建防抖处理函数
  const debouncedProcessImage = useCallback(
    debounce(() => {
      if (imageUrl) {
        processImage();
      }
    }, 300),
    [params, palette, imageUrl]
  );

  // 创建不防抖处理函数
  const DirectlyProcessImage = useCallback(() => {
    if (imageUrl) {
      processImage();
    }
  }, [params, palette, imageUrl]);

  useEffect(() => {
    // 只有当参数或调色板实际发生变化时才触发处理
    const paramsChanged = JSON.stringify(params) !== JSON.stringify(lastProcessedParams);
    const paletteChanged = JSON.stringify(palette) !== JSON.stringify(lastProcessedPalette);
    const imageChanged = imageUrl !== ''; // 新图加载（或从无到有）

    const shouldProcess = (paramsChanged||paletteChanged||imageChanged)&&imageUrl;

    if (!imageUrl){
      log.debug('Detected that the image address does not exist');
    }
    else{
      log.debug('Detected the existence of image address');
    }
    if (!imageChanged){
      log.debug('Detected no change in image address');
    }
    else{
      log.debug('Detected a change in image address');
    }

    if (!paramsChanged){
      log.debug('Detected no changes in parameters');
    }else{
      log.debug('Detected parameter changes');
      log.debug('params', params);
      log.debug('lastProcessedParams', lastProcessedParams);
    }

    if (!paletteChanged){
      log.debug('Detected no change in the color palette');
    }else{
      log.debug('Detected a change in the color palette');
      log.debug('palette', palette);
      log.debug('lastProcessedPalette', lastProcessedPalette);
    }

    if (params.useDithering && shouldProcess) {
      log.info('Jitter mode: delayed processing');
      debouncedProcessImage();
    }
    else if (!params.useDithering && shouldProcess) {
      log.info('Non jitter mode: Immediate processing');
      DirectlyProcessImage();
    }
    else{
      log.info('Parameter not changed: Not processed');
    }
  }, [params, palette, imageUrl]);

  // ==================== 下载功能 ====================

  // 电脑端下载函数
  const downloadForDesktop = () => {
    if (!processedImage) return;

    try {
      const timestamp = new Date().getTime();
      const filename = `pixel-art-${timestamp}.png`;

      const link = document.createElement('a');
      link.href = processedImage;
      link.download = filename;
      link.style.display = 'none';

      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);

      log.info('Desktop download initiated');

      // 显示成功提示
      toast({
        title: '下载开始',
        description: '文件正在下载中...',
        status: 'success',
        duration: 3000,
        isClosable: true,
        position: 'top-right'
      });
    } catch (error) {
      log.error('Desktop download failed:', error);
      toast({
        title: '下载失败',
        description: '请尝试使用其他浏览器',
        status: 'error',
        duration: 5000,
        isClosable: true,
      });
    }
  };

  // 移动端下载函数 - 显示指导
  const downloadForMobile = () => {
    log.info('Mobile device detected, showing save guide');
    setShowMobileGuide(true);
  };

  // 统一的下载处理函数
  const handleDownload = () => {
    if (!processedImage || isDownloading) return;

    setIsDownloading(true);

    const { isMobile } = detectDevice();

    if (isMobile) {
      downloadForMobile();
    } else {
      downloadForDesktop();
    }

    // 重置下载状态
    setTimeout(() => setIsDownloading(false), 1000);
  };

  // 移动端保存指导内容
  const MobileSaveGuide = () => (
    <AlertDialog
      isOpen={showMobileGuide}
      leastDestructiveRef={cancelRef}
      onClose={() => setShowMobileGuide(false)}
      size="lg"
    >
      <AlertDialogOverlay>
        <AlertDialogContent>
          <AlertDialogHeader fontSize="lg" fontWeight="bold">
            📱 如何保存图片
          </AlertDialogHeader>

          <AlertDialogBody>
            <Box mb={4}>
              <strong>在移动设备上保存图片的方法：</strong>
            </Box>

            <Box mb={3}>
              <Box fontWeight="bold" color="blue.600" mb={1}>方法一：长按图片保存</Box>
              <Box pl={4}>
                <Box>1. 返回到图片预览页面</Box>
                <Box>2. 长按上方的像素艺术图片</Box>
                <Box>3. 选择"保存图像"或"下载图像"</Box>
              </Box>
            </Box>

            <Box mb={3}>
              <Box fontWeight="bold" color="green.600" mb={1}>方法二：截图保存</Box>
              <Box pl={4}>
                <Box>1. 确保图片完全显示在屏幕上</Box>
                <Box>2. 使用手机截图功能截取图片</Box>
                <Box>3. 在相册中裁剪保留需要的部分</Box>
              </Box>
            </Box>

            <Box mt={4} p={3} bg="gray.50" borderRadius="md">
              <Box fontSize="sm" color="gray.600">
                💡 提示：由于移动浏览器限制，无法直接通过按钮下载文件。
                推荐使用"长按保存"方法获得最佳质量的图片。
              </Box>
            </Box>
          </AlertDialogBody>

          <AlertDialogFooter>
            <Button ref={cancelRef} onClick={() => setShowMobileGuide(false)}>
              关闭
            </Button>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialogOverlay>
    </AlertDialog>
  );

  // 移动端图片预览提示
  const MobileImageHint = () => {
    const { isMobile } = detectDevice();

    if (!isMobile || !processedImage) return null;

    return (
      <Box
        position="absolute"
        bottom="0"
        left="0"
        right="0"
        bg="rgba(0,0,0,0.7)"
        color="white"
        p={2}
        textAlign="center"
        fontSize="xs"
        borderBottomLeftRadius="8px"
        borderBottomRightRadius="8px"
      >
        💡 长按图片可直接保存
      </Box>
    );
  };

  if (!imageUrl) {
    return (
      <Box border="2px dashed" borderColor="gray.300" p={8} textAlign="center">
        请先上传图片
      </Box>
    );
  }

  return (
    <Box>
      {/* 移动端保存指导对话框 */}
      <MobileSaveGuide />

      <Box position="relative" mb={4}>
        {isProcessing && (
          <Box
            position="absolute"
            top="50%"
            left="50%"
            transform="translate(-50%, -50%)"
            zIndex={10}
          >
            <Spinner size="xl" />
          </Box>
        )}
        {processedImage && (
          <Box position="relative">
            <img
              src={processedImage}
              alt="Pixelated"
              style={{
                width: '100%',
                maxWidth: '600px',
                opacity: isProcessing ? 0.5 : 1,
                transition: 'opacity 0.3s',
                borderRadius: '8px'
              }}
            />
            {/* 移动端图片保存提示 */}
            <MobileImageHint />
          </Box>
        )}
      </Box>

      {processedImage && !isProcessing && (
        <Button
          colorScheme="blue"
          onClick={handleDownload}
          isLoading={isDownloading}
          loadingText="处理中..."
          width="100%"
        >
          下载像素图
        </Button>
      )}
    </Box>
  );
};
